package account;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * Anzeigeklasse fuer ein Piechart (Kuchendiagramm).<br>
 * Dieses zeigt die relativen Verteilungen der Kontostaende in einem Kuchendiagramm an.
 *
 * @author Patrick Bauer
 */
public class AccountChartView extends JPanel implements Observer {
    /**
     * Die anzuzeigenden Scheiben des Kuchendiagramms.
     */
    private PieSlice[] slices;

    /**
     * Platzhalterlabel zur Anzeige, wenn noch keine Werte eingebenen wurden.
     */
    private JLabel noValues = new JLabel("Noch keine Werte vorhanden.");


    /**
     * Fuegt das Platzhalterlabel der Anzeige hinzu
     */
    public AccountChartView() {
        this.add(this.noValues);
    }

     /**
     * Wird vom Observable aufgerufen und bekommt Daten einer Tranksaktion.<br>
     * Liest aus dem Model die Kontostaende und Farben der einzelnen Kontos um diese im Kuchendiagramm zu rendern.
     *
     * @param o das AccountModel
     * @param arg die AccountAction
     */
    @Override
    public void update(Observable o, Object arg) {
        AccountModel model = (AccountModel) o;
        
        this.noValues.setVisible(false);
        this.slices = new PieSlice[model.getAccountCount()];
        
        for(int i = 0; i < model.getAccountCount(); i++) {
            this.slices[i] = new PieSlice(model.getBalancebyIndex(i), model.getColorbyIndex(i));
        }
        
        this.repaint();
    }

    /**
     * Setzt die Parameter des zu zeichnenen Kuchendiagramms.<br>
     * Achtet auf gleiche Seitenverhaeltniesse und Abstaende zum Fensterrand.
     *
     * @param g
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        
        this.noValues.setLocation(this.getWidth()/2-this.noValues.getWidth()/2, this.getHeight()/2 - this.noValues.getHeight()/2);
        
        Rectangle rec = new Rectangle();
        
        if(this.getWidth() > this.getHeight()){
            rec.setBounds((this.getWidth()/2-(this.getHeight()/2))+20, 20, this.getHeight()-40, this.getHeight()-40);
        } else {
            rec.setBounds(20, this.getHeight()/2-this.getWidth()/2+20, this.getWidth()-40, this.getWidth()-40);
        }

        if(this.slices != null) {
            this.drawPie((Graphics2D) g, rec, this.slices);
        }
    }
    
    /**
     * Zeichnet das eigentliche Kuchendiagram in den angebene Bereich aus den gegebenen Scheiben.
     *
     * @param g das Grafikobjekt
     * @param area der Bereich in dem gezeichnet wird
     * @param slices die einzelnen Scheiben des Kuchendiagramms
     */
    public void drawPie(Graphics2D g, Rectangle area, PieSlice[] slices) {
        double total = 0.0D;
        for (int i=0; i<slices.length; i++) {
            total += slices[i].getValue();
        }

        double curValue = 0.0D;
        int startAngle = 0;
        for (int i=0; i<slices.length; i++) {
            startAngle = (int)(curValue * 360 / total);
            int arcAngle = (int)(slices[i].getValue() * 360 / total);

            if (i == slices.length-1) {
                arcAngle = 360 - startAngle;
            }

            g.setColor(slices[i].getColor());
            g.fillArc(area.x, area.y, area.width, area.height, startAngle, arcAngle);

            curValue += slices[i].getValue();
        }
    }
    
    
    /**
     * Klasse zum Speichern einer Scheibe des Kuchendiagramms.
     *
     * @author Patrick Bauer
     */
    public class PieSlice {
        /**
         * Wert der Kuchenscheibe.
         */
        private double value;

        /**
         * Farbe der Kuchenscheibe
         */
        private Color color;

        /**
         * Setzt den Wert und die Farbe des Kuchenstueckes.
         *
         * @param value der Wert
         * @param color die Farbe
         */
        public PieSlice(double value, Color color) {
            this.value = value;
            this.color = color;
        }

        /**
         * Liefert den Wert der Kuchenscheibe
         *
         * @return der Wert
         */
        public double getValue() {
            return value;
        }

        /**
         * Liefert die Farbe der Kuchenscheibe.
         *
         * @return die Farbe
         */
        public Color getColor() {
            return color;
        }
    }

}
